package com.xzh.http;

import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.HttpCookie;
import java.util.HashMap;
import java.util.Map;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class MainActivity extends AppCompatActivity {

    private TextView okHttpPostData,okHttpGetData;
    private ProgressBar okHttpDownloadFileProgress,okHttpInterceptorProgress;
    public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
    private OkHttpClient client;
    private String[] permissions = new String[] {
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE
    };
    private static final int  MY_PERMISSION_REQUEST_CODE = 1000;
    private Response mResponse;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
//        client = new OkHttpClient();
        initView();
        initOkHttpClient();
    }

    private void initView() {
        okHttpPostData = findViewById(R.id.ok_http_post_data);
        okHttpGetData = findViewById(R.id.ok_http_get_data);
        okHttpDownloadFileProgress = findViewById(R.id.ok_http_download_file_progress);
        okHttpInterceptorProgress = findViewById(R.id.ok_http_download_file_interceptor_progress);
    }
    private void initOkHttpClient(){

        client = new  OkHttpClient.Builder().addNetworkInterceptor(new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Response response = chain.proceed(chain.request());
                return response.newBuilder().body(new ResponseInterceptorBody(response.body(),new Pro())).build();
            }
        }).build();
    }

    class Pro implements OkHttpInterceptorCallBack{
        @Override
        public void onProgress(final int progress) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    LogUtils.log("---------------------------------------  >>>>>onProgress   "+progress);
                    okHttpInterceptorProgress.setProgress(progress);
                }
            });
        }

        @Override
        public void onFinish() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    LogUtils.log("---------------------------------------  >>>>>>>>>>>>>  ");
                    LogUtils.show(MainActivity.this,"finish");
                }
            });
        }
    }
    public void okHttpInterceptrorProgressClick(View view) {

        //OKHTTP 拦截器的使用
        // 首先创建一个类，继承自ResponseBody(下载) , RequestBody(上传)
        Request request = new Request.Builder()
                .url(AppConfig.DOWNLOAD_URL)
                .build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                LogUtils.log("onFailure  >>>  "+e.toString());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                //用拦截器的时候，这里必须要写这一行，否则不会被执行
                response.body().string();
//                LogUtils.log("response  >>>  ");
//                LogUtils.log("response  >>>  "+response.body().string());

            }
        });

    }

    public void okHttpFileDownloadClick(View view) {

        Request request = new Request.Builder().url(AppConfig.DOWNLOAD_URL).build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                LogUtils.log("exception : "+e.toString());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                MainActivity.this.mResponse = response;
                getPermission();
            }
        });
    }
    private void getPermission(){
        boolean isAllGranted = checkPermission(permissions);
        if (isAllGranted){
            //权限允许则执行操作
            downloadFile();
        }else{
            //动态申请权限
            ActivityCompat.requestPermissions(this,permissions, MY_PERMISSION_REQUEST_CODE);
        }
    }

    private boolean checkPermission(String[] permissions){
        for (String permission : permissions){
            if (ContextCompat.checkSelfPermission(this,permission) != PackageManager.PERMISSION_GRANTED){
                // 只要有一个权限没有被授予, 则直接返回 false
                return false;
            }
        }
        return true;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode ==  MY_PERMISSION_REQUEST_CODE){
            boolean isAllGranted = true;

            for (int grant : grantResults) {
                if (grant == PackageManager.PERMISSION_GRANTED){
                    isAllGranted = false;
                    break;
                }
            }
            if (isAllGranted){
                downloadFile();
            }else{
                //如果权限申请之后，用户不允许权限，那么跳转到设置里面，让用户打开权限
                openAppDetails();
            }
        }
    }

    //打开系统的设置，让用户开启权限
    private void openAppDetails() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage("备份通讯录需要访问 “通讯录” 和 “外部存储器”，请到 “应用信息 -> 权限” 中授予！");
        builder.setPositiveButton("去手动授权", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Intent intent = new Intent();
                intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                intent.addCategory(Intent.CATEGORY_DEFAULT);
                intent.setData(Uri.parse("package:" + getPackageName()));
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
                intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
                startActivity(intent);
            }
        });
        builder.setNegativeButton("取消", null);
        builder.show();
    }

    private void downloadFile() {
        FileOutputStream fos = null;
        InputStream is = mResponse.body().byteStream();
        byte[] bytes = new byte[1024];
        try {
            if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
                String filePath = Environment.getExternalStorageDirectory().getAbsolutePath()+"/okhttpDir";
                File path = new File(filePath);
                File file = new File(filePath, "ok_htto.png");
                if (!path.exists()){
                    path.mkdirs();
                }
                if (!file.exists()){
                    file.createNewFile();
                }else{
                    file.delete();
                    file.createNewFile();
                }

                long totalSize = mResponse.body().contentLength();
                long sum = 0;
                long len = 0;
                fos = new FileOutputStream(file);
                while (len != -1) {
                    len = is.read(bytes);
                    fos.write(bytes);
                    sum += len;
                    int progress = (int) ((sum * 1.0f / totalSize) * 100);
                    Message message = new Message();
                    message.what = 1;
                    message.arg1 = progress;
                    handler.sendMessage(message);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            LogUtils.log("exception >>>>>  "+e.toString()+"  0 ");
        }finally {
            if (is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case  1:
                    int pro = msg.arg1;
                    okHttpDownloadFileProgress.setProgress(pro);
                    break;
                default:
                    break;
            }
        }
    };

    // get 请求 简单使用
    public void okHttpGetClick(View view) {
        LogUtils.log("okHttoGetClick : ");
        long time = System.currentTimeMillis() / 1000;
        String header = HttpUtils.getSecretSign(AppConfig.GET_URL, time);

        final Request request = new Request.Builder()
                .addHeader("Authorization",header)
                .url(AppConfig.BASE_URL+AppConfig.GET_URL+"?api_key="+AppConfig.API_KEY+"&timestamp="+time)
                .build();

        //enqueue :  异步的方法
        // execute :  同步（会阻塞线程）
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                LogUtils.log("ex -------------- > :  "+e.toString());
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) {
                    String result = response.body().string();
                    LogUtils.log("response ---- > :  "+ result);
                    // 在子线程中更新UI报错了 ：  CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
                    showGetResData(result);
                    // 必须要关闭RequestBody,否则可能造成内存泄露
                    if (response.body() != null) {
                        response.body().close();
                    }
                }
            }
        });
    }

    private void showGetResData(final String res) {
        //子线程转UI线程
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (!TextUtils.isEmpty(res)){
                    okHttpGetData.setText(res);
                }else {
                    Log.i("null ","null");
                }
            }
        });
    }

    //post 请求  简单使用
    public void okHttpPostClick(View view) {
        // post 请求 通过  form表单参数的形式
        getDataWithFormPostRequest();

        //post 请求  通过  json 参数的形式（推荐使用）
//        getDataWithJsonPostRequest();
    }



    private void getDataWithJsonPostRequest() {
        // 以json的形式提交post请求
        long time = System.currentTimeMillis() / 1000;

        JSONObject jsonObject = new JSONObject();

        try {

            jsonObject.put("api_key",AppConfig.API_KEY);
            jsonObject.put("timestamp",time+"");
            jsonObject.put("product","2");

        } catch (JSONException e) {
            e.printStackTrace();
        }
        String jsonParams = jsonObject.toString();
        RequestBody requestBody = RequestBody.create(JSON,jsonParams);
        String header = HttpUtils.getSecretSign(AppConfig.POST_URL,time);

        Request request = new Request.Builder()
                .addHeader("Authorization",header)
                .url(AppConfig.BASE_URL + AppConfig.POST_URL)
                .post(requestBody)
                .build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                showPostResData("json  exception :  \n " + e.toString());
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()){
                    showPostResData("json :  \n " + response.body().string());
                }
            }
        });
    }

    private void getDataWithFormPostRequest(){
        // 以Form表单的形式提交post请求
        long time = System.currentTimeMillis() / 1000;
        //RequestBody 其实是一个抽象类，是不能创建对象的，Ctrl+左键进去看源码，类名 -> 右键 -> goto ->implementation，可以查看实现这个类的 子类。
        RequestBody requestBody = new FormBody.Builder()
                .add("user_id","17560")
                .add("page","1")
                .add("size","10")
                .add("api_key",AppConfig.API_KEY)
                .add("timestamp",time+"")
                .build();
        String header = HttpUtils.getSecretSign(AppConfig.POST_URL,time);
        Request request = new Request.Builder()
                .addHeader("Authorization",header)
                .url(AppConfig.BASE_URL+AppConfig.POST_URL)
                .post(requestBody)
                .build();
        //enqueue :  异步的方法
        // execute :  同步（会阻塞线程）
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                showPostResData("form  exception :  \n "+e.toString());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()){
                    showPostResData("form :  \n "+response.body().string());
                }
            }
        });
    }

    private void showPostResData(final String res) {
        //子线程转UI线程
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (!TextUtils.isEmpty(res)){
                    okHttpPostData.setText(res);
                }else {
                    Log.i("null ","null");
                }
            }
        });
    }
}
